/*
 * Copyright (C), 2013-2017, 汇通达网络有限公司
 * FileName: JobServlet.java
 * Author:   杨振宁
 * Date:     2017-4-6 下午5:04:58
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.htd.apm.job;

import com.htd.htdapmcommon.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;



@WebServlet(name="jobServlet",urlPatterns="/jobServlet")
public class JobServlet extends HttpServlet{
	
	private static final Logger LOGGER = LoggerFactory.getLogger(JobServlet.class);
	
	private static final long serialVersionUID = 1L;
	
	private static JobExecutor jobExecutor;
	
	private static ConcurrentHashMap<String, Method> cachedMethod = new ConcurrentHashMap<String, Method>();
	
	private static ConcurrentHashMap<String, String> methodBlackList = new ConcurrentHashMap<String, String>();
	
	public JobServlet(){
		super();
	}
		
	
	@Override 
    public void init() throws ServletException {
		super.init();
		if (null == jobExecutor) {
			jobExecutor = (JobExecutor)SpringContextUtil.getBean("jobClientExecutor");
		}
	}
	
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) {
		executeJob(request,response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) {
		executeJob(request,response);
	}
	
	
	private void executeJob(HttpServletRequest request, HttpServletResponse response) {
		String springBeanName = request.getParameter(JobConstans.BEAN_NAME);
		String methodName = request.getParameter(JobConstans.METHOD_NAME);
		
		if (StringUtil.isNull(springBeanName) || StringUtil.isNull(methodName)) {
			return;
		}
		
		methodName = methodName.trim();
		if (methodBlackList.containsKey(methodName)) {
			return;
		}
		springBeanName = springBeanName.trim();
		Object object = initBean(springBeanName);
		Method method = initMethod(object,springBeanName,methodName);
		doJob(object,method);
	}
	
	private Object initBean(String springBeanName) {
		Object obj = null;
		try {
			obj = SpringContextUtil.getBean(springBeanName);
		} catch (BeansException e) {
			return null;
		}
		return obj;
	}
	
	private Method initMethod (Object obj,String springBeanName,String methodName) {
		if (null == obj) {
			return null;
		}
		
		Method method = null;
		String methodCacheKey = springBeanName + methodName;
		method = cachedMethod.get(methodCacheKey);
		if (null != method) {
			return method;
		}
		
		try {
			method = obj.getClass().getMethod(methodName);
		} catch (NoSuchMethodException e) {
			putMethodBlackList(methodName);
			LOGGER.error("并没有此方法,方法名{}",methodName,e);
			return null;
		} catch (SecurityException e) {
			putMethodBlackList(methodName);
			LOGGER.error("该方法因为安全问题不许执行,方法名{}",methodName,e);
			return null;
		}
		
		if (null != method) {
			cachedMethod.put(methodCacheKey, method);
		}
		
		return method;
	}
	
	private void putMethodBlackList (String methodName) {
		if (!methodBlackList.containsKey(methodName)) {
			// 这里因为多线程问题,可能会出现put异常,不管它
			try {
				methodBlackList.put(methodName, methodName);
			} catch (Exception e) {
				// skip
			}
		}
	}
	
	private void doJob (Object object,Method method) {
		if (null == object || null == method) {
			return;
		}
		
		jobExecutor.executor(object, method);
	}
	
	
	
	
	
	
	
}
